package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.common.R;
import com.itheima.dto.*;
import com.itheima.entity.RoleAdd;
import com.itheima.entity.SysMenu;
import com.itheima.entity.SysRole;
import com.itheima.entity.SysRoleMenu;
import com.itheima.mapper.SysRoleMapper;
import com.itheima.service.SysMenuService;
import com.itheima.service.SysRoleMenuService;
import com.itheima.service.SysRoleService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色表 服务实现类
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Autowired
    private SysMenuService sysMenuService;


    /**
     * 获取角色分页数据
     *
     * @param page
     * @param limit
     * @param name
     * @return
     */
    @Override
    public RoleDto getRoleList(String page, String limit, String name) {
        Page<SysRole> pageInfo = new Page<>(Long.parseLong(page), Long.parseLong(limit));
        RoleDto roleDto = new RoleDto();
        roleDto.setUpdateDate(LocalDateTime.now());
        //创建条件构造器
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(name), SysRole::getName, name);
        //根据修改的时间降序排列
        wrapper.orderByDesc(SysRole::getUpdateDate);
        List<RoleDataDto> dataDtoList = new ArrayList<>();

        //查询基本信息
        this.page(pageInfo, wrapper);
        for (SysRole record : pageInfo.getRecords()) {
            RoleDataDto roleDataDto = new RoleDataDto();
            BeanUtils.copyProperties(record, roleDataDto);
            roleDataDto.setRole_id(record.getId());
            LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
            //根据中间表的role_id查询关联的菜单信息
            queryWrapper.eq(SysRoleMenu::getRoleId, record.getId());
            List<SysRoleMenu> menuList = sysRoleMenuService.list(queryWrapper);
            String roleMenus = "";
            int a = 0;
            for (SysRoleMenu sysRoleMenu : menuList) {
                a++;
                if (menuList.size() == a) {
                    roleMenus += sysRoleMenu.getMenuId();
                    break;
                }
                roleMenus += (sysRoleMenu.getMenuId() + ",");
            }
            roleDataDto.setRole_menus(roleMenus);
            dataDtoList.add(roleDataDto);
        }
        //设置返回的分页数据
        roleDto.setData(dataDtoList);
        roleDto.setCount((int) pageInfo.getTotal());
        roleDto.setCurrentPage((int) pageInfo.getCurrent());
        roleDto.setPageSize((int) pageInfo.getSize());
        roleDto.setTotalPages((int) pageInfo.getPages());
        return roleDto;
    }

    /**
     * 添加角色数据
     *
     * @param roleAdd
     */
    @Override
    @Transactional
    public void add(RoleAdd roleAdd) {
        //先保存基本信息
        SysRole sysRole = new SysRole();
        sysRole.setDescription(roleAdd.getDescription());
        sysRole.setName(roleAdd.getName());
        sysRole.setCreateDate(LocalDateTime.now());
        this.save(sysRole);

        //获取所有的角色关联的menuids
        List<String> menuids = roleAdd.getMenuids();
        for (String menuid : menuids) {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setRoleId(sysRole.getId());
            roleMenu.setMenuId(menuid);
            //保存关联信息到中间表
            sysRoleMenuService.save(roleMenu);
        }
//        List<SysRoleMenu> roleMenuList = sysRoleMenuService.list(lambdaQueryWrapper);
//        for (SysRoleMenu sysRoleMenu : roleMenuList) {
//            if(sysRoleMenu.getMenuId()!=null){
//                SysRoleMenu roleMenu = new SysRoleMenu();
//                roleMenu.setMenuId(sysRoleMenu.getMenuId());
//                roleMenu.setRoleId(sysRoleMenu.getRoleId());
//                //保存关联信息到中间表
//                sysRoleMenuService.save(roleMenu);
//            }
//        }
    }


    /**
     * 角色删除并删除关联菜单信息
     *
     * @param id
     * @return
     */
    @Override
    public void delRoleWithMenu(String id) {
        //删除基本信息
        this.removeById(id);
        //删除 SysRoleMenu 对应的数据
        LambdaQueryWrapper<SysRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleMenu::getRoleId, id);
        sysRoleMenuService.remove(wrapper);
    }

    /**
     * 数据回显
     *
     * @param
     * @return
     */
    @Override
    public RowInfoDto getRowInfo(String id) {
        return null;
    }

    @Override
    public SysRoleMenuDto rowInfo(String id) {
        SysRoleMenuDto sysRoleMenuDto = new SysRoleMenuDto();
        SysRole sysRole = this.getById(id);
        BeanUtils.copyProperties(sysRole, sysRoleMenuDto);

        //当前角色id对应的菜单权限
        LambdaQueryWrapper<SysRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleMenu::getRoleId, id);
        List<SysRoleMenu> roleMenuList = sysRoleMenuService.list(wrapper);
        List<SysMenu> allMenu = new ArrayList<>();

        for (SysRoleMenu sysRoleMenu : roleMenuList) {
            SysMenu sysMenu = sysMenuService.getById(sysRoleMenu.getMenuId());
            allMenu.add(sysMenu);
        }

        // --------authList----------
        // 查询根节点集合
        List<SysMenuDto> rootMenu = new ArrayList<>();
        // 遍历所有菜单,查出根节点, pid = 0
        for (SysMenu menu : allMenu) {
            if (menu.getPid() == 0) {
                SysMenuDto sysMenuDto = new SysMenuDto();
                BeanUtils.copyProperties(menu, sysMenuDto);
                rootMenu.add(sysMenuDto);
            }
        }

        // 遍历根节点,为根节点设置子节点,getChild
        for (SysMenuDto menu : rootMenu) {
            List<SysMenuDto> childList = getChild(menu.getId(), allMenu);
            menu.setChildren(childList);
        }
        // --------authList----------
        sysRoleMenuDto.setAuthList(rootMenu);
        return sysRoleMenuDto;
    }


    private List<SysMenuDto> getChild(Integer id, List<SysMenu> allMenu) {
        // 定义子节点集合
        List<SysMenuDto> childList = new ArrayList<>();
        for (SysMenu menu : allMenu) {
            // 如果 传来的id 和 pid 一样,则添加进 childList 中
            if (id.equals(menu.getPid())) {
                SysMenuDto menuDto = new SysMenuDto();
                BeanUtils.copyProperties(menu, menuDto);
                childList.add(menuDto);
            }
        }

        // 如果 childList 大小为0,说明没有子节点,则返回,结束递归
        if (childList.size() == 0) {
            return childList;
        }

        // 不为0,递归
        for (SysMenuDto sysMenuDto : childList) {
            sysMenuDto.setChildren(getChild(sysMenuDto.getId(), allMenu));
        }
        return childList;
    }

    /*@GetMapping("/rowInfo")
    public R<SysRoleDto> rowInfo(String id){
        SysRole sysRole = sysRoleService.getById(id);
        SysRoleDto sysRoleDto = new SysRoleDto();
        BeanUtils.copyProperties(sysRole,sysRoleDto);
        if (sysRole!=null){
            LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysRoleMenu::getRoleId,sysRoleDto.getId());
            List<SysRoleMenu> roleMenuList = sysRoleMenuService.list(queryWrapper);
            List<SysMenu> list=roleMenuList.stream().map(item->{
                SysMenu sysMenu = sysMenuService.getById(item.getMenuId());
                return sysMenu;
            }).collect(Collectors.toList());
            sysRoleDto.setAuthList(list);
            return R.success(sysRoleDto);
        }
        return R.error("获取角色信息失败");
    }*/


    /**
     * 修改角色及其关联的菜单信息
     * @param sysRoleMenuDto
     */
    @Transactional
    @Override
    public void updateRoleWithMenu(SysRoleMenuDto sysRoleMenuDto) {
        SysRole sysRole = new SysRole();
        //复制sysRoleMenuDto中的基本信息,并且排除创建时间和修改时间
        BeanUtils.copyProperties(sysRoleMenuDto,sysRole,"create_date","update_date");
        //先修改角色信息
        this.updateById(sysRole);

        List<String> menuids = sysRoleMenuDto.getMenuids();
        //在SysRoleMenu表中先删除角色对应的menuid
        LambdaQueryWrapper<SysRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleMenu::getRoleId, sysRoleMenuDto.getId());
        sysRoleMenuService.remove(wrapper);

        for (String menuid : menuids) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(sysRoleMenuDto.getId());
            sysRoleMenu.setMenuId(menuid);
            sysRoleMenuService.save(sysRoleMenu);
        }
    }
}
